package soup.net;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JLabel;

import soup.net.Messages.Chat;
import soup.net.Messages.Login;
import soup.net.Messages.UserList;

import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;
import com.esotericsoftware.minlog.Log;

public class SoupServer {
	static public final int defaultPort = 55555;
	
	Server server;
	
	public SoupServer () throws IOException {
		//init the server. give it a subclass of Connection that stores the state we need per connection
		server = new Server() {
			protected Connection newConnection() {
				return new SoupConnection();
			}
		};
		
		//register all of the message classes with the server's serializer
		Messages.register(server);
		
		server.addListener(new Listener() {
			public void received(Connection c, Object obj) {
				SoupConnection sc = (SoupConnection)c;
				
				if(obj instanceof Login) {
					//new connection
					sc.name = ((Login)obj).name;
					//send a "____ connected" message to everyone but the new client:
					Chat message = new Chat();
					message.text = sc.name + " connected.";
					server.sendToAllExceptTCP(c.getID(), message);
					//send everyone the name list
					updateUserList();
					return;
				}
				if(obj instanceof Chat) {
					//prepend client's name and send to everyone
					Chat response = new Chat();
					response.text = sc.name + ": " + ((Chat)obj).text;
					server.sendToAllTCP(response);
				}
			}
			
			public void disconnected(Connection c) {
				SoupConnection sc = (SoupConnection)c;
				Chat message = new Chat();
				message.text = sc.name + " disconnected.";
				server.sendToAllTCP(message);
				updateUserList();
			}
		});
		
		server.bind(defaultPort);
		server.start();
		
		JFrame frame = new JFrame("Chat Server");
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosed (WindowEvent evt) {
				server.stop();
			}
		});
		frame.getContentPane().add(new JLabel("Close to stop the chat server."));
		frame.setSize(320, 200);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}
	
	void updateUserList() {
		Connection[] connections = server.getConnections();
		
		UserList list = new UserList();
		list.names = new String[connections.length];
		for(int i = 0; i < connections.length; ++i)
			list.names[i] = ((SoupConnection)connections[i]).name;
		
		server.sendToAllTCP(list);
	}
	
	//custom connection type -- stores connection state
	static class SoupConnection extends Connection {
		public String name;
	}
	
	public static void main(String[] args) throws IOException {
		Log.set(Log.LEVEL_DEBUG);
		new SoupServer();
	}
}
